package zju.lzy.service.device;

import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.Setter;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import zju.lzy.dto.Device;
import zju.lzy.dto.IOTMessage;
import zju.lzy.util.BSUtil;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * @author lzy
 */
@Getter
@Setter
public class WorkerThread extends Thread {

    private final static Logger logger = LoggerFactory.getLogger(WorkerThread.class);

    final static String DEFAULT_MQTT_SERVER = "tcp://localhost:1883";

    private boolean running = true;
    private int deviceId;
    private String mqttServer = DEFAULT_MQTT_SERVER;
    private String topic;
    private String clientPrefix;
    private int qos = 2;
    private double initLat = 119.9, initLon = 30.1;


    public WorkerThread() {

    }

    public WorkerThread(
            int deviceId,
            String mqttServer,
            String topic,
            String clientPrefix,
            int qos,
            double initLat,
            double initLon) {
        this.deviceId = deviceId;
        this.mqttServer = mqttServer;
        this.topic = topic;
        this.clientPrefix = clientPrefix;
        this.qos = qos;
        this.initLat = initLat;
        this.initLon = initLon;
    }

    public WorkerThread(Device device) {
        this.deviceId = device.getDeviceId();
        this.topic = device.getTopic();
        this.clientPrefix = device.getClientPrefix();
        this.qos = device.getQos();
        this.initLat = device.getInitLat();
        this.initLon = device.getInitLon();
    }

    public WorkerThread(Device device, String mqttServer) {
        this(device);
        this.mqttServer = mqttServer;
    }

    @Override
    public void run() {
        try {
            String clientId;
            String content;
            MemoryPersistence persistence = new MemoryPersistence();

            Random rand = new Random();

            clientId = clientPrefix + String.format("%d", deviceId);
            MqttClient mqttClient = new MqttClient(mqttServer, clientId, persistence);
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setCleanSession(true);
            logger.info("Connecting to broker: " + mqttServer);
            mqttClient.connect();
            logger.info("Connected");
            while (running) {
                //根据配置确定随机等待时间
                int interval = rand.nextInt(BSUtil.iotProperties.getMaxInterval());
                Thread.sleep(interval * 1000);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                Date now = new Date();
                int value = rand.nextInt(100);
                // 产生消息
                IOTMessage msg = new IOTMessage();
                msg.setSender(deviceId);
                msg.setTopic(topic);
                msg.setClientId(clientId);
                msg.setInfo("Device Data " + sdf.format(now));
                msg.setValue(value);
                //超过80告警
                msg.setAlert(value > 80 ? 1 : 0);
                rand.nextFloat();
                //根据杭州经纬度随机生成设备位置信息
                msg.setLon(initLon + rand.nextFloat() * 0.3);
                msg.setLat(initLat + rand.nextFloat() * 0.2);
                msg.setTimestamp(now.getTime());
                content = JSONObject.toJSONString(msg);
                logger.info("将要f发布数据：{}", JSONObject.parseObject(content, IOTMessage.class));
                MqttMessage message = new MqttMessage(content.getBytes());
                message.setQos(qos);
                mqttClient.publish(topic, message);
                logger.info("数据发布成功，发布者：" + getName());
            }
            mqttClient.disconnect();
            logger.info("Disconnected");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
